-module(matrix2).

-export([divide/1, adjust_inlet/2, adjust_outlet/2]).

-compile(export_all).

-include("scatter_region.hrl").

-include_lib("eunit/include/eunit.hrl").
-define(MO, ?MODULE).

adjust_entrylet({Entrylet1,Entrylet2}, {Begin, End} = _EntryRange, {From,To}, {Face2Begin,Face2End}) ->
    if 
        ((6 + Entrylet1) rem 12) == Entrylet2 ->
            Sign = -1;
        true ->
            Sign = 1
    end,

    if 
        End > Begin ->
            Delta = 1;
        Begin > End ->
            Delta = -1;
        true ->
            Delta = 0
    end,
    Mid = (Begin + End) / 2.0,
    if
        From >= Mid ->
            NewEntrylet1 = (12 + Entrylet1 + Delta) rem 12,
            NewEntrylet2 = (12 + Entrylet2 + Delta * Sign) rem 12;
        To =< Mid ->
            NewEntrylet1 = (12 + Entrylet1 - Delta) rem 12,
            NewEntrylet2 = (12 + Entrylet2 - Delta * Sign) rem 12
    end,
    
    FaceMid = (Face2Begin + Face2End) / 2.0,
    if 
        ((Entrylet1 rem 3) == 0) and ((Entrylet2 rem 3) == 0) ->
            Head = {FaceMid, Face2End},
            Tail = {Face2Begin, FaceMid},
            if 
                ((12 + Entrylet2 - NewEntrylet2) rem 12) == 1 ->
                    Face2 = Tail;
                ((12 + Entrylet2 - NewEntrylet2) rem 12) == 11 ->
                    Face2 = Head
            end,
            {NewEntrylet1, NewEntrylet2, Face2};
        ((Entrylet1 rem 3) =/= 0) and ((Entrylet2 rem 3) =/= 0) ->
            {Entrylet1, Entrylet2, {Face2Begin, Face2End}};
        true ->
            {NewEntrylet1, NewEntrylet2, {Face2Begin, Face2End}}
                    
    end.

-spec adjust_inlet(TR::topo_region(), NewFace::face()) -> {'stop_here'|'continue', topo_region()}.
adjust_inlet(#topological_region{inlet=OldInlet, outlet=OldOutlet, outerface=Face} = TR, NewFace) ->
    EdgeRange = edge_range(TR#topological_region.region, OldInlet),
    if 
        EdgeRange == NewFace ->
            {stop_here, TR#topological_region{interface=EdgeRange}};
        true ->
        {NewIn, NewOutlet, NewOuterface} = 
            adjust_entrylet({OldInlet,OldOutlet}, EdgeRange, NewFace, Face),
        if
            OldOutlet == NewOutlet ->
                {stop_here, 
                    TR#topological_region{
                        inlet = NewIn, outlet = NewOutlet, interface = NewFace
                    }};
            true ->
                {continue, 
                    TR#topological_region{
                        inlet = NewIn, outlet = NewOutlet, interface = NewFace, outerface = NewOuterface
                    }}
        end
    end.

-spec adjust_outlet(TR::topo_region(), PredRange::face()) -> {'stop_here'|'continue', topo_region()}.
adjust_outlet(#topological_region{inlet=OldInlet, outlet=OldOutlet, interface=Face} = TR, NewFace) ->
    EdgeRange = edge_range(TR#topological_region.region, OldOutlet),
    if
        EdgeRange == NewFace ->
            {stop_here, TR#topological_region{outerface=EdgeRange}};
        true ->
        {NewOutlet, NewInlet, NewInterface} = 
            adjust_entrylet({OldOutlet,OldInlet}, EdgeRange, NewFace, Face),
        if
            OldInlet == NewInlet ->
                {stop_here,
                    TR#topological_region{
                        inlet = NewInlet, outlet = NewOutlet, outerface = NewFace
                    }};
            true ->
                {continue, 
                    TR#topological_region{
                        inlet = NewInlet, outlet = NewOutlet, outerface = NewFace, interface = NewInterface
                    }}  
        end
    end.

edge_range(#region{left=Left, right=Right}, 0) ->
    {Left, Right};
edge_range(#region{top=Top, bottom=Bottom}, 3) ->
    {Top, Bottom};
edge_range(#region{left=Left, right=Right}, 6) ->
    {Right, Left};
edge_range(#region{top=Top, bottom=Bottom}, 9) ->
    {Bottom, Top};
edge_range(#region{left=L, right=R}, 1) ->
    {(L + R) / 2.0, R};
edge_range(#region{top=T, bottom=B}, 2) ->
    {T, (T + B) / 2.0};
edge_range(#region{top=T, bottom=B}, 4) ->
    {(T + B) / 2.0, B};
edge_range(#region{left=L, right=R}, 5) ->
    {R, (L + R) / 2.0};
edge_range(#region{left=L, right=R}, 7) ->
    {(L + R) / 2.0, L};
edge_range(#region{top=T, bottom=B}, 8) ->
    {B, (B + T) / 2.0};
edge_range(#region{top=T, bottom=B}, 10) ->
    {(B + T) / 2.0, T};
edge_range(#region{left=L, right=R}, 11) ->
    {L, (L + R) / 2.0}.


divide(#topological_region{inlet=undefined, outlet=undefined, region=Region}) ->
    if 
        abs(Region#region.top - Region#region.bottom) >= abs(Region#region.right - Region#region.left) ->
            {Left, Right} = divide_vertical(Region),
            TR1 = new_topo_region(Left, 4, 2),
            %#topological_region{inlet=4, outlet=2, square_flag=false, region=Left},
            TR2 = new_topo_region(Right, 10, 8),
            %#topological_region{inlet=10,outlet=8, square_flag=false, region=Right},
            {TR1#topological_region{square_flag=false}, TR2#topological_region{square_flag=false}};
        true ->
            {Top, Bottom} = divide_horizonal(Region),
            TR1 = new_topo_region(Top, 7, 5),
            %#topological_region{inlet=7, outlet=5, square_flag=false, region=Top},
            TR2 = new_topo_region(Bottom, 5, 7),
            %#topological_region{inlet=5, outlet=7, square_flag=false, region=Bottom},
            {TR1#topological_region{square_flag=false}, TR2#topological_region{square_flag=false}}
    end;
divide(#topological_region{square_flag=true, interface=Interface, outerface=Outerface} = TopologicalRegion) ->
    {TR1, TR2} = divide_square(TopologicalRegion),
    NewInterface = intersect_range(TR1#topological_region.interface, Interface),
    NewOuterface = intersect_range(TR2#topological_region.outerface, Outerface),
    {TR1#topological_region{interface=NewInterface}, TR2#topological_region{outerface=NewOuterface}};
divide(#topological_region{square_flag=false, interface=Interface, outerface=Outerface} = TopologicalRegion) ->
    {TR1, TR2} = divide_rectangle(TopologicalRegion),
    NewInterface = intersect_range(TR1#topological_region.interface, Interface),
    NewOuterface = intersect_range(TR2#topological_region.outerface, Outerface),
    {TR1#topological_region{interface=NewInterface}, TR2#topological_region{outerface=NewOuterface}}.

intersect_range({X1, Y1}, {X2, Y2}) when X2 < Y2 ->
    if 
        X1 =< X2 ->
            X = X2;
        X1 > X2 ->
            X = X1
    end,
    if 
        Y1 =< Y2 ->
            Y = Y1;
        Y1 > Y2 ->
            Y = Y2
    end,
    {X, Y};
intersect_range({X1, Y1}, {X2, Y2}) when X2 > Y2 ->
    if
        X1 =< X2 ->
            X = X1;
        X1 > X2 ->
            X = X2
    end,
    if 
        Y1 =< Y2 ->
            Y = Y2;
        Y1 > Y2 ->
            Y = Y1
    end,
    {X, Y}.


crosscut(#topological_region{inlet=0, outlet=Out}=TopologicalRegion) ->
    R = TopologicalRegion#topological_region.region,
    {TopRegion, BottomRegion} = divide_horizonal(R),
    case Out of
        4 ->
            Top = new_topo_region(TopRegion, 0, 6),
            %#topological_region{inlet=0,outlet=6, region=TopRegion},
            Bottom = new_topo_region(BottomRegion, 0, 3),
            %#topological_region{inlet=0,outlet=3, region=BottomRegion},
            {Top,Bottom};
        6 ->
            Top = new_topo_region(TopRegion, 0, 6),
            %#topological_region{inlet=0,outlet=6, region=TopRegion},
            Bottom = new_topo_region(BottomRegion, 0, 6),
            %#topological_region{inlet=0,outlet=6, region=BottomRegion},
            {Top,Bottom};
        8 ->
            Top = new_topo_region(TopRegion, 0, 6),
            %Top = #topological_region{inlet=0,outlet=6, region=TopRegion},
            %Bottom = #topological_region{inlet=0,outlet=9, region=BottomRegion},
            Bottom = new_topo_region(BottomRegion, 0, 9),
            {Top,Bottom}
    end;
crosscut(#topological_region{inlet=2, outlet=Out}=TopologicalRegion) ->
    R = TopologicalRegion#topological_region.region,
    {TopRegion, BottomRegion} = divide_horizonal(R),
    case Out of
        4 ->
            %Top = #topological_region{inlet=3,outlet=6,region=TopRegion},
            %Bottom = #topological_region{inlet=0,outlet=3,region=BottomRegion},
            Top = new_topo_region(TopRegion, 3, 6),
            Bottom = new_topo_region(BottomRegion, 0, 3),
            {Top,Bottom};
        6 ->
            %Top = #topological_region{inlet=3,outlet=6,region=TopRegion},
            %Bottom = #topological_region{inlet=0,outlet=6,region=BottomRegion},
            Top = new_topo_region(TopRegion, 3, 6),
            Bottom = new_topo_region(BottomRegion, 0, 6),
            {Top,Bottom};
        8 ->
            %Top = #topological_region{inlet=3,outlet=6,region=TopRegion},
            %Bottom = #topological_region{inlet=0,outlet=9,region=BottomRegion},
            Top = new_topo_region(TopRegion, 3, 6),
            Bottom = new_topo_region(BottomRegion, 0, 9),
            {Top,Bottom}
    end;
crosscut(#topological_region{inlet=4, outlet=Out} = TopologicalRegion) ->
    R = TopologicalRegion#topological_region.region,
    {TopRegion, BottomRegion} = divide_horizonal(R),
    case Out of
        10 ->
            %Top = #topological_region{inlet=6,outlet=9,region=TopRegion},
            %Bottom = #topological_region{inlet=3,outlet=0,region=BottomRegion},
            Top = new_topo_region(TopRegion, 6, 9),
            Bottom = new_topo_region(BottomRegion, 3, 0),
            {Top,Bottom};
        0 ->
            %Top = #topological_region{inlet=6,outlet=0,region=TopRegion},
            %Bottom = #topological_region{inlet=3,outlet=0,region=BottomRegion},
            Top = new_topo_region(TopRegion, 6, 0),
            Bottom = new_topo_region(BottomRegion, 3, 0),
            {Top,Bottom};
        2 ->
            %Top = #topological_region{inlet=6,outlet=3,region=TopRegion},
            %Bottom = #topological_region{inlet=3,outlet=0,region=BottomRegion},
            Top = new_topo_region(TopRegion, 6, 3),
            Bottom = new_topo_region(BottomRegion, 3, 0),
            {Top,Bottom}
    end.

divide_rectangle(#topological_region{inlet=In, region=#region{left=L,top=T,right=R,bottom=B}} = TopologicalRegion) 
when (abs(B-T) > abs(R-L)) ->
    if 
        (In == 0) or (In == 2) ->
            to_squares(crosscut(TopologicalRegion));
        (In == 4) ->
            {TR1, TR2} = crosscut(TopologicalRegion),
            to_squares({TR2, TR1});
        (In == 6) or (In == 8) ->
            {M1,M2} = crosscut(rotate_counterclockwise_quarter(rotate_counterclockwise_quarter(TopologicalRegion))),
            to_squares({rotate_clockwise_quarter(rotate_clockwise_quarter(M1)),
                    rotate_clockwise_quarter(rotate_clockwise_quarter(M2))});
        (In == 10) ->
            {M1,M2} = crosscut(rotate_counterclockwise_quarter(rotate_counterclockwise_quarter(TopologicalRegion))),
            to_squares({rotate_clockwise_quarter(rotate_clockwise_quarter(M2)),
                    rotate_clockwise_quarter(rotate_clockwise_quarter(M1))});
        true ->
            throw("sHouLd nOt be Here!")
    end;
divide_rectangle(#topological_region{inlet=In} = TopologicalRegion) ->
    if 
        (In == 1) ->
            {M1,M2} = crosscut(rotate_clockwise_quarter(TopologicalRegion)),
            to_squares({rotate_counterclockwise_quarter(M2), rotate_counterclockwise_quarter(M1)});
        (In == 11) or (In == 9) ->
            {M1,M2} = crosscut(rotate_clockwise_quarter(TopologicalRegion)),
            to_squares({rotate_counterclockwise_quarter(M1), rotate_counterclockwise_quarter(M2)});
        (In == 3) or (In == 5) ->
            {M1,M2} = crosscut(rotate_counterclockwise_quarter(TopologicalRegion)),
            to_squares({rotate_clockwise_quarter(M1), rotate_clockwise_quarter(M2)});
        (In == 7) ->
            {M1,M2} = crosscut(rotate_counterclockwise_quarter(TopologicalRegion)),
            to_squares({rotate_clockwise_quarter(M2), rotate_clockwise_quarter(M1)});
        true ->
            throw("SHold NoT be hERe!")
    end.

to_rectangle(TR) ->
    TR#topological_region{square_flag=false}.
to_square(TR) ->
    TR#topological_region{square_flag=true}.

to_rectangles({TR1, TR2}) ->
    {to_rectangle(TR1), to_rectangle(TR2)}.
to_squares({TR1, TR2}) ->
    {to_square(TR1), to_square(TR2)}.

new_topo_region(Region, Inlet, Outlet) ->
    Interface = edge_range(Region, Inlet),
    Outerface = edge_range(Region, Outlet),
    #topological_region{
        inlet = Inlet, outlet = Outlet,
        interface = Interface, outerface = Outerface,
        region = Region
    }.

cut(#topological_region{inlet=In, outlet=Out}=TopologicalRegion) when (In == 1) or (In == 2) ->
    R = TopologicalRegion#topological_region.region,
    case Out of
        3 ->
            {TopRegion, BottomRegion} = divide_horizonal(R),
            TR1 = shrink_vertical(In, TopRegion),
            TR2 = new_topo_region(BottomRegion, 11, Out),
            {TR1, TR2};
%        (Out > 3) and (Out < 6) ->
        4 ->
            {TopRegion, BottomRegion} = divide_horizonal(R),
            TR1 = shrink_vertical(In, TopRegion),
            TR2 = new_topo_region(BottomRegion, 11, Out-1),
            {TR1, TR2};
        5 ->
            {TopRegion, BottomRegion} = divide_horizonal(R),
            TR1 = shrink_vertical(In, TopRegion),
            TR2 = new_topo_region(BottomRegion, 11, Out),
            {TR1, TR2};
        6 ->
            {TopRegion, BottomRegion} = divide_horizonal(R),
            TR1 = shrink_vertical(In, TopRegion),
            TR2 = new_topo_region(BottomRegion, 11, Out-1),
            {TR1, TR2};

        9 ->
            {LeftRegion, RightRegion} = divide_vertical(R),
            TR1 = shrink_horizonal(In, RightRegion),
            TR2 = new_topo_region(LeftRegion, 4, Out+1),
            {TR1, TR2};
%        (Out > 9) and (Out < 12) ->
        10 ->
            {LeftRegion, RightRegion} = divide_vertical(R),
            TR2 = new_topo_region(LeftRegion, 4, Out),
            TR1 = shrink_horizonal(In, RightRegion),
            {TR1, TR2};
        11 ->
            {LeftRegion, RightRegion} = divide_vertical(R),
            TR2 = new_topo_region(LeftRegion, 4, 0),
            TR1 = shrink_horizonal(In, RightRegion),
            {TR1, TR2};
        0 ->
            {LeftRegion, RightRegion} = divide_vertical(R),
            TR2 = new_topo_region(LeftRegion, 4, Out),
            TR1 = shrink_horizonal(In, RightRegion),
            {TR1, TR2}
    end;
cut(#topological_region{inlet=0, outlet=Out}=TopologicalRegion) ->
    R = TopologicalRegion#topological_region.region,
    case Out of
        1 ->
            {LeftRegion, RightRegion} = divide_vertical(R),
            TR1 = new_topo_region(LeftRegion, 0, 4),
            TR2 = new_topo_region(RightRegion, 8, 0),
            {TR1, TR2};
        2 ->
            {LeftRegion, RightRegion} = divide_vertical(R),
            TR1 = new_topo_region(LeftRegion, 0, 4),
            TR2 = new_topo_region(RightRegion, 8, Out),
            {TR1, TR2};
        3 ->
            {LeftRegion, RightRegion} = divide_vertical(R),
            TR1 = new_topo_region(LeftRegion, 0, 4),
            TR2 = new_topo_region(RightRegion, 8, 2),
            {TR1, TR2};
        4 ->    
            {TopRegion, BottomRegion} = divide_horizonal(R),
            TR1 = new_topo_region(TopRegion, 1, 7),
            TR2 = new_topo_region(BottomRegion, 11, 3),
            {TR1, TR2};
        5 ->
            {TopRegion, BottomRegion} = divide_horizonal(R),
            TR1 = new_topo_region(TopRegion, 1, 7),
            TR2 = new_topo_region(BottomRegion, 11, 5),
            {TR1, TR2};
        6 ->
            {TopRegion, BottomRegion} = divide_horizonal(R),
            TR1 = new_topo_region(TopRegion, 1, 7),
            TR2 = new_topo_region(BottomRegion, 11, 5),
            {TR1, TR2};
        7 ->
            {TopRegion, BottomRegion} = divide_horizonal(R),
            TR1 = new_topo_region(TopRegion, 11, 5),
            TR2 = new_topo_region(BottomRegion, 1, Out),
            {TR1, TR2};
        8 ->
            {TopRegion, BottomRegion} = divide_horizonal(R),
            TR1 = new_topo_region(TopRegion, 11, 5),
            TR2 = new_topo_region(BottomRegion, 1, 9),
            {TR1, TR2};
        9 ->
            {TopRegion, BottomRegion} = divide_horizonal(R),
            TR1 = new_topo_region(TopRegion, 11, 5),
            TR2 = new_topo_region(BottomRegion, 1, 9),
            {TR1, TR2};
        10 ->
            {LeftRegion, RightRegion} = divide_vertical(R),
            TR1 = new_topo_region(RightRegion, 0, 8),
            TR2 = new_topo_region(LeftRegion, 4, Out),
            {TR1, TR2};
        11 ->
            {LeftRegion, RightRegion} = divide_vertical(R),
            TR1 = new_topo_region(RightRegion, 0, 8),
            TR2 = new_topo_region(LeftRegion, 4, 0),
            {TR1, TR2}
    end.
        
divide_square(#topological_region{inlet=In}=TopologicalRegion) when (In == 0) or (In == 1) or (In == 2) ->
    to_rectangles(cut(TopologicalRegion));
divide_square(#topological_region{inlet=In}=TopologicalRegion) when (In == 3) or (In == 4) or (In == 5) ->
    TR = rotate_counterclockwise_quarter(TopologicalRegion),
    {M1,M2} = cut(TR),
    to_rectangles({rotate_clockwise_quarter(M1), rotate_clockwise_quarter(M2)});
divide_square(#topological_region{inlet=In}=TopologicalRegion) when (In == 6) or (In == 7) or (In == 8) ->
    TR = rotate_counterclockwise_quarter(rotate_counterclockwise_quarter(TopologicalRegion)),
    {M1,M2} = cut(TR),
    to_rectangles({rotate_clockwise_quarter(rotate_clockwise_quarter(M1)),
            rotate_clockwise_quarter(rotate_clockwise_quarter(M2))});
divide_square(#topological_region{inlet=In}=TopologicalRegion) when (In == 9) or (In == 10) or (In == 11) ->
    TR = rotate_clockwise_quarter(TopologicalRegion),
    {M1,M2} = cut(TR),
    to_rectangles({rotate_counterclockwise_quarter(M1),
            rotate_counterclockwise_quarter(M2)}).

shrink_vertical(In, TopRegion) ->
    case In of
        1 ->
            new_topo_region(TopRegion, In, 7);
        2 ->
            new_topo_region(TopRegion, 3, 7)
    end.

shrink_horizonal(In, RightRegion) ->
    case In of
        1 ->
            new_topo_region(RightRegion, 0, 8);
        2 ->
            new_topo_region(RightRegion, In, 8)
    end.

divide_horizonal(#region{top=T,left=L,bottom=B,right=R}) ->
    Top = #region{top=T, left=L, right=R, bottom=T+(B-T)/2},
    Bottom = #region{top=T+(B-T)/2, left=L, right=R, bottom=B},
    {Top, Bottom}.

divide_vertical(#region{top=T, left=L, bottom=B, right=R}) ->
    Left = #region{top=T, left=L, right=L+(R-L)/2, bottom=B},
    Right = #region{top=T, left=L+(R-L)/2, right=R, bottom=B},
    {Left, Right}.

%%
%% rotate counterclockwise
rotate_ccw_quarter(#region{left=L,top=T,right=R,bottom=B}) ->
    #region{left=-T, top=R, right=-B, bottom=L}.

%%
%% rotate cloclkwise
rotate_cw_quarter(#region{left=L,top=T,right=R,bottom=B}) ->
    #region{left=B, top=-L, right=T,bottom=-R}.


rotate_cw_edge({Tail, End}, Entry) when Entry == 11; Entry == 0; Entry == 1 ->
    {-Tail, -End};
rotate_cw_edge({Tail, End}, Entry) when Entry == 2; Entry == 3; Entry == 4 ->
    {Tail, End};
rotate_cw_edge({Tail, End}, Entry) when Entry == 5; Entry == 6; Entry == 7 ->
    {-Tail, -End};
rotate_cw_edge({Tail, End}, Entry) when Entry == 8; Entry == 9; Entry == 10 ->
    {Tail, End}.


rotate_ccw_edge({Tail, End}, Entry) when Entry == 11; Entry == 0; Entry == 1 ->
    {Tail, End};
rotate_ccw_edge({Tail, End}, Entry) when Entry == 2; Entry == 3; Entry == 4 ->
    {-Tail, -End};
rotate_ccw_edge({Tail, End}, Entry) when Entry == 5; Entry == 6; Entry == 7 ->
    {Tail, End};
rotate_ccw_edge({Tail, End}, Entry) when Entry == 8; Entry == 9; Entry == 10 ->
    {-Tail, -End}.
%%
%%
%%
%%
rotate_clockwise_quarter(#topological_region{inlet=In, outlet=Out, interface={I1,I2},outerface={O1,O2},region=Region}) ->
    #topological_region{
        inlet = (In + 3) rem 12, 
        outlet = (Out + 3) rem 12,
        interface = rotate_cw_edge({I1,I2}, In),
        outerface = rotate_cw_edge({O1,O2}, Out),
        region = rotate_cw_quarter(Region)
    }.

rotate_counterclockwise_quarter(#topological_region{inlet=In, outlet=Out, interface={I1,I2},outerface={O1,O2},region=Region}) ->
    #topological_region{
        inlet = (In + 9) rem 12,
        outlet = (Out + 9) rem 12,
        interface = rotate_ccw_edge({I1,I2}, In),
        outerface = rotate_ccw_edge({O1,O2}, Out),
        region = rotate_ccw_quarter(Region)
    }.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% unit test
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
adjust_inlet_test_() ->
    TR = #topological_region{
        inlet=0, outlet=3, 
        interface = {20.0, 40.0},
        outerface = {50.0, 30.0},
        region=#region{left=20.0,top=50.0, right=40.0, bottom=30.0}},
    {continue, NR} = ?MO:adjust_inlet(TR, {30.0, 40.0}),
    ExpectTR = #topological_region{
        inlet=1, outlet=4,
        interface = {30.0, 40.0}, 
        outerface = {40.0, 30.0},
        region=#region{left=20.0,top=50.0, right=40.0, bottom=30.0}},

    TR1 = #topological_region{
        inlet=2, outlet=4, 
        interface = {50.0, 40.0},
        outerface = {40.0, 30.0},
        region=#region{left=20.0,top=50.0, right=40.0, bottom=30.0}},
    {_stop_here, NR1} = ?MO:adjust_inlet(TR1, {50.0, 45.0}),
    ExpectTR1 = #topological_region{
        inlet=2, outlet=4,
        interface = {50.0, 45.0}, 
        outerface = {40.0, 30.0},
        region=#region{left=20.0,top=50.0, right=40.0, bottom=30.0}},

    TR2 = #topological_region{
        inlet=3, outlet=6, 
        interface = {60.0, 20.0},
        outerface = {40.0, 20.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},
    {continue, NR2} = ?MO:adjust_inlet(TR2, {60.0, 40.0}),
    ExpectTR2 = #topological_region{
        inlet=2, outlet=5,
        interface = {60.0, 40.0}, 
        outerface = {40.0, 30.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},

    TR3 = #topological_region{
        inlet=9, outlet=3, 
        interface = {20.0, 60.0},
        outerface = {60.0, 20.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},
    {continue, NR3} = ?MO:adjust_inlet(TR3, {40.0, 45.0}),
    ExpectTR3 = #topological_region{
        inlet=10, outlet=2,
        interface = {40.0, 45.0}, 
        outerface = {60.0, 40.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},

    TR4 = #topological_region{
        inlet=0, outlet=9, 
        interface = {20.0, 40.0},
        outerface = {20.0, 60.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},
    {continue, NR4} = ?MO:adjust_inlet(TR4, {30.0, 40.0}),
    ExpectTR4 = #topological_region{
        inlet=1, outlet=10,
        interface = {30.0, 40.0}, 
        outerface = {40.0, 60.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},

    TR5 = #topological_region{
        inlet=3, outlet=0, 
        interface = {50.0, 30.0},
        outerface = {20.0, 40.0},
        region=#region{left=20.0,top=50.0, right=40.0, bottom=30.0}},
    {stop_here, NR5} = ?MO:adjust_inlet(TR5, {50.0, 30.0}),
    ExpectTR5 = #topological_region{
        inlet=3, outlet=0,
        interface = {50.0, 30.0}, 
        outerface = {20.0, 40.0},
        region=#region{left=20.0,top=50.0, right=40.0, bottom=30.0}},
    
    TR6 = #topological_region{
                region = #region{left = 0,top = 1024, right = 512.0,bottom = 512.0},
                inlet = 6,outlet = 3,
                interface = {512,0},
                outerface = {1024,512},
                square_flag = true
        },
    {continue, NR6} = ?MO:adjust_inlet(TR6, {256, 0}),
    ExpectTR6 = #topological_region{
                region = #region{left = 0,top = 1024, right = 512.0,bottom = 512.0},
                inlet = 7,outlet = 4,
                interface = {256,0},
                outerface = {1024,512}
        },

    [?_assertEqual(ExpectTR, NR),
        ?_assertEqual(ExpectTR1, NR1),
        ?_assertEqual(ExpectTR2, NR2),
        ?_assertEqual(ExpectTR3, NR3),
        ?_assertEqual(ExpectTR4, NR4),
        ?_assertEqual(ExpectTR5, NR5),
        ?_assertEqual(ExpectTR6, NR6)].

adjust_outlet_test_() ->
    TR = #topological_region{
        inlet=1, outlet=4, 
        interface = {30.0, 40.0},
        outerface = {40.0, 30.0},
        region=#region{left=20.0,top=50.0, right=40.0, bottom=30.0}},
    {stop_here, NR} = ?MO:adjust_outlet(TR, {40.0, 35.0}),
    ExpectTR = #topological_region{
        inlet=1, outlet=4,
        interface = {30.0, 40.0}, 
        outerface = {40.0, 35.0},
        region=#region{left=20.0,top=50.0, right=40.0, bottom=30.0}},

    TR1 = #topological_region{
        inlet=2, outlet=4, 
        interface = {60.0, 50.0},
        outerface = {40.0, 20.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},
    {stop_here, NR1} = ?MO:adjust_outlet(TR1, {25.0, 20.0}),
    ExpectTR1 = #topological_region{
        inlet=2, outlet=4,
        interface = {60.0, 50.0}, 
        outerface = {25.0, 20.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},

    TR2 = #topological_region{
        inlet=3, outlet=6, 
        interface = {60.0, 20.0},
        outerface = {40.0, 20.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},
    {continue, NR2} = ?MO:adjust_outlet(TR2, {40.0, 30.0}),
    ExpectTR2 = #topological_region{
        inlet=2, outlet=5,
        interface = {60.0, 40.0}, 
        outerface = {40.0, 30.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},

    TR3 = #topological_region{
        inlet=9, outlet=3, 
        interface = {20.0, 60.0},
        outerface = {60.0, 20.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},
    {continue, NR3} = ?MO:adjust_outlet(TR3, {60.0, 40.0}),
    ExpectTR3 = #topological_region{
        inlet=10, outlet=2,
        interface = {40.0, 60.0}, 
        outerface = {60.0, 40.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},
    
    TR4 = #topological_region{
        inlet=0, outlet=9, 
        interface = {20.0, 40.0},
        outerface = {20.0, 60.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},
    {continue, NR4} = ?MO:adjust_outlet(TR4, {20.0, 40.0}),
    ExpectTR4 = #topological_region{
        inlet=11, outlet=8,
        interface = {20.0, 30.0}, 
        outerface = {20.0, 40.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},

    TR5 = #topological_region{
        inlet=3, outlet=0, 
        interface = {50.0, 30.0},
        outerface = {20.0, 40.0},
        region=#region{left=20.0,top=50.0, right=40.0, bottom=30.0}},
    {stop_here, NR5} = ?MO:adjust_outlet(TR5, {20.0, 40.0}),
    ExpectTR5 = #topological_region{
        inlet=3, outlet=0,
        interface = {50.0, 30.0}, 
        outerface = {20.0, 40.0},
        region=#region{left=20.0,top=50.0, right=40.0, bottom=30.0}},

    [?_assertEqual(ExpectTR, NR),
        ?_assertEqual(ExpectTR1, NR1),
        ?_assertEqual(ExpectTR2, NR2),
        ?_assertEqual(ExpectTR3, NR3),
        ?_assertEqual(ExpectTR4, NR4),
        ?_assertEqual(ExpectTR5, NR5)].
%%% 
%%  +---+
%%  |   |
%%  |   |
%%  |   |
%%  +---+
%%
divide_rectangle_0_4_test_() ->
    TR = #topological_region{square_flag=false,
        inlet=0, outlet=4,
        interface={20.0, 40.0}, outerface={40.0,20.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},
    {Top,Bottom} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=0, outlet=6, 
        interface={20.0, 40.0}, outerface={40.0, 20.0},
        region=#region{left=20.0,top=60.0,right=40.0,bottom=40.0}},
    ExpectBottom = #topological_region{inlet=0, outlet=3, 
        interface={20.0, 40.0}, outerface={40.0, 20.0},
        region=#region{left=20.0,top=40.0,right=40.0,bottom=20.0}},
    [?_assertEqual(ExpectTop, Top),
        ?_assertEqual(ExpectBottom, Bottom)].
    
divide_rectangle_0_6_test() ->
    TR = #topological_region{inlet=0, outlet=6,square_flag=false,
        interface={20.0, 40.0}, outerface={40.0, 20.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},
    {Top,Bottom} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=0, outlet=6, 
        interface={20.0, 40.0}, outerface={40.0, 20.0},
        region=#region{left=20.0,top=60.0,right=40.0,bottom=40.0}},
    ExpectBottom = #topological_region{inlet=0, outlet=6, 
        interface={20.0, 40.0}, outerface={40.0, 20.0},
        region=#region{left=20.0,top=40.0,right=40.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).

divide_rectangle_0_8_test() ->
    TR = #topological_region{inlet=0, outlet=8,square_flag=false,
        interface={20.0, 40.0}, outerface={20.0, 40.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},
    {Top,Bottom} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=0, outlet=6, 
        interface={20.0, 40.0}, outerface={40.0, 20.0},
        region=#region{left=20.0,top=60.0,right=40.0,bottom=40.0}},
    ExpectBottom = #topological_region{inlet=0, outlet=9, 
        interface={20.0, 40.0}, outerface={20.0, 40.0},
        region=#region{left=20.0,top=40.0,right=40.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).

divide_rectangle_2_8_test() ->
    TR = #topological_region{inlet=2, outlet=8,square_flag=false,
        interface={60.0, 40.0}, outerface={20.0, 40.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},
    {Top,Bottom} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=3, outlet=6, 
        interface={60.0, 40.0}, outerface={40.0, 20.0},
        region=#region{left=20.0,top=60.0,right=40.0,bottom=40.0}},
    ExpectBottom = #topological_region{inlet=0, outlet=9, 
        interface={20.0, 40.0}, outerface={20.0, 40.0},
        region=#region{left=20.0,top=40.0,right=40.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).

divide_rectangle_4_10_test() ->
    TR = #topological_region{inlet=4, outlet=10,square_flag=false,
        interface={40.0, 20.0}, outerface={40.0, 60.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},
    {Bottom,Top} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=6, outlet=9, 
        interface={40.0, 20.0}, outerface={40.0, 60.0},
        region=#region{left=20.0,top=60.0,right=40.0,bottom=40.0}},
    ExpectBottom = #topological_region{inlet=3, outlet=0, 
        interface={40.0, 20.0}, outerface={20.0, 40.0},
        region=#region{left=20.0,top=40.0,right=40.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).

divide_rectangle_4_0_test() ->
    TR = #topological_region{inlet=4, outlet=0,square_flag=false,
        interface={40.0, 20.0}, outerface={20.0, 40.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},
    {Bottom,Top} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=6, outlet=0, 
        interface={40.0, 20.0}, outerface={20.0, 40.0},
        region=#region{left=20.0,top=60.0,right=40.0,bottom=40.0}},
    ExpectBottom = #topological_region{inlet=3, outlet=0, 
        interface={40.0, 20.0}, outerface={20.0, 40.0},
        region=#region{left=20.0,top=40.0,right=40.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).

divide_rectangle_6_0_test() ->
    TR = #topological_region{inlet=6, outlet=0,square_flag=false,
        interface={40.0, 20.0}, outerface={20.0, 40.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},
    {Bottom,Top} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=6, outlet=0, 
        interface={40.0, 20.0}, outerface={20.0, 40.0},
        region=#region{left=20.0,top=60.0,right=40.0,bottom=40.0}},
    ExpectBottom = #topological_region{inlet=6, outlet=0, 
        interface={40.0, 20.0}, outerface={20.0, 40.0},
        region=#region{left=20.0,top=40.0,right=40.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).

divide_rectangle_6_2_test() ->
    TR = #topological_region{inlet=6, outlet=2,square_flag=false,
        interface={40.0, 20.0}, outerface={60.0, 40.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},
    {Bottom,Top} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=6, outlet=3, 
        interface={40.0, 20.0}, outerface={60.0, 40.0},
        region=#region{left=20.0,top=60.0,right=40.0,bottom=40.0}},
    ExpectBottom = #topological_region{inlet=6, outlet=0, 
        interface={40.0, 20.0}, outerface={20.0, 40.0},
        region=#region{left=20.0,top=40.0,right=40.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).

divide_rectangle_6_10_test() ->
    TR = #topological_region{inlet=6, outlet=10,square_flag=false,
        interface={60.0, 20.0}, outerface={40.0, 20.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},
    {Bottom,Top} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=6, outlet=9, 
        interface={40.0, 20.0}, outerface={40.0, 60.0},
        region=#region{left=20.0,top=60.0,right=40.0,bottom=40.0}},
    ExpectBottom = #topological_region{inlet=6, outlet=0, 
        interface={40.0, 20.0}, outerface={20.0, 40.0},
        region=#region{left=20.0,top=40.0,right=40.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).

divide_rectangle_8_10_test() ->
    TR = #topological_region{inlet=8, outlet=10,square_flag=false,
        interface={20.0, 40.0}, outerface={40.0, 60.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},
    {Bottom,Top} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=6, outlet=9, 
        interface={40.0, 20.0}, outerface={40.0, 60.0},
        region=#region{left=20.0,top=60.0,right=40.0,bottom=40.0}},
    ExpectBottom = #topological_region{inlet=9, outlet=0, 
        interface={20.0, 40.0}, outerface={20.0, 40.0},
        region=#region{left=20.0,top=40.0,right=40.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).

divide_rectangle_8_2_test() ->
    TR = #topological_region{inlet=8, outlet=2, square_flag=false,
        interface={20.0, 40.0}, outerface={60.0, 40.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},
    {Bottom,Top} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=6, outlet=3, 
        interface={40.0, 20.0}, outerface={60.0, 40.0},
        region=#region{left=20.0,top=60.0,right=40.0,bottom=40.0}},
    ExpectBottom = #topological_region{inlet=9, outlet=0, 
        interface={20.0, 40.0}, outerface={20.0, 40.0},
        region=#region{left=20.0,top=40.0,right=40.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).

divide_rectangle_8_0_test() ->
    TR = #topological_region{inlet=8, outlet=0,square_flag=false,
        interface={20.0, 40.0}, outerface={20.0, 40.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},
    {Bottom,Top} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=6, outlet=0, 
        interface={40.0, 20.0}, outerface={20.0, 40.0},
        region=#region{left=20.0,top=60.0,right=40.0,bottom=40.0}},
    ExpectBottom = #topological_region{inlet=9, outlet=0, 
        interface={20.0, 40.0}, outerface={20.0, 40.0},
        region=#region{left=20.0,top=40.0,right=40.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).

divide_rectangle_10_4_test() ->
    TR = #topological_region{inlet=10, outlet=4, square_flag=false,
        interface={40.0, 60.0}, outerface={60.0, 20.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},
    {Top, Bottom} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=9, outlet=6, 
        interface={40.0, 60.0}, outerface={40.0, 20.0},
        region=#region{left=20.0,top=60.0,right=40.0,bottom=40.0}},
    ExpectBottom = #topological_region{inlet=0, outlet=3, 
        interface={20.0, 40.0}, outerface={40.0, 20.0},
        region=#region{left=20.0,top=40.0,right=40.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).

divide_rectangle_10_6_test() ->
    TR = #topological_region{inlet=10, outlet=6, square_flag=false,
        interface={40.0, 60.0}, outerface={40.0, 20.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},
    {Top, Bottom} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=9, outlet=6, 
        interface={40.0, 60.0}, outerface={40.0, 20.0},
        region=#region{left=20.0,top=60.0,right=40.0,bottom=40.0}},
    ExpectBottom = #topological_region{inlet=0, outlet=6, 
        interface={20.0, 40.0}, outerface={40.0, 20.0},
        region=#region{left=20.0,top=40.0,right=40.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).

divide_rectangle_10_8_test() ->
    TR = #topological_region{inlet=10, outlet=8, square_flag=false,
        interface={40.0, 60.0}, outerface={20.0, 40.0},
        region=#region{left=20.0,top=60.0, right=40.0, bottom=20.0}},
    {Top, Bottom} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=9, outlet=6, 
        interface={40.0, 60.0}, outerface={40.0, 20.0},
        region=#region{left=20.0,top=60.0,right=40.0,bottom=40.0}},
    ExpectBottom = #topological_region{inlet=0, outlet=9, 
        interface={20.0, 40.0}, outerface={20.0, 40.0},
        region=#region{left=20.0,top=40.0,right=40.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).
%%
%% +---------+
%% |         |
%% |         |
%% +---------+
%% 
divide_rectangle_1_7_test() ->
    TR = #topological_region{inlet=1, outlet=7,square_flag=false,
        interface={65.0, 120.0}, outerface={65.0, 10.0},
        region=#region{left=10.0,top=100.0, right=120.0, bottom=20.0}},
    {Right, Left} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=3, outlet=6, 
        interface={100.0, 20.0}, outerface={65.0, 10.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=0, outlet=9, 
        interface={65.0, 120.0}, outerface={20.0, 100.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).

divide_rectangle_9_1_test() ->
    TR = #topological_region{inlet=9, outlet=1,square_flag=false,
        interface={20.0, 100.0}, outerface={65.0, 120.0},
        region=#region{left=10.0,top=100.0, right=120.0, bottom=20.0}},
    {Left,Right} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=9, outlet=3, 
        interface={20.0, 100.0}, outerface={100.0, 20.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=9, outlet=0, 
        interface={20.0, 100.0}, outerface={65.0, 120.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).

divide_rectangle_11_1_test() ->
    TR = #topological_region{inlet=11, outlet=1,square_flag=false,
        interface={10.0, 65.0}, outerface={65.0, 120.0},
        region=#region{left=10.0,top=100.0, right=120.0, bottom=20.0}},
    {Left,Right} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=0, outlet=3, 
        interface={10.0, 65.0}, outerface={100.0, 20.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=9, outlet=0, 
        interface={20.0, 100.0}, outerface={65.0, 120.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).

divide_rectangle_11_3_test() ->
    TR = #topological_region{inlet=11, outlet=3,square_flag=false,
        interface={10.0, 65.0}, outerface={100.0, 20.0},
        region=#region{left=10.0,top=100.0, right=120.0, bottom=20.0}},
    {Left,Right} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=0, outlet=3, 
        interface={10.0, 65.0}, outerface={100.0, 20.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=9, outlet=3, 
        interface={20.0, 100.0}, outerface={100.0, 20.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).

divide_rectangle_11_5_test() ->
    TR = #topological_region{inlet=11, outlet=5,square_flag=false,
        interface={10.0, 65.0}, outerface={120.0, 65.0},
        region=#region{left=10.0,top=100.0, right=120.0, bottom=20.0}},
    {Left,Right} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=0, outlet=3, 
        interface={10.0, 65.0}, outerface={100.0, 20.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=9, outlet=6, 
        interface={20.0, 100.0}, outerface={120.0, 65.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).

divide_rectangle_7_1_test() ->
    TR = #topological_region{inlet=7, outlet=1,square_flag=false,
        interface={65.0, 10.0}, outerface={65.0, 120.0},
        region=#region{left=10.0,top=100.0, right=120.0, bottom=20.0}},
    {Left, Right} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=6, outlet=3, 
        interface={65.0, 10.0}, outerface={100.0, 20.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=9, outlet=0, 
        interface={20.0, 100.0}, outerface={65.0, 120.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).

divide_rectangle_7_3_test() ->
    TR = #topological_region{inlet=7, outlet=3,square_flag=false,
        interface={65.0, 10.0}, outerface={100.0, 20.0},
        region=#region{left=10.0,top=100.0, right=120.0, bottom=20.0}},
    {Left, Right} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=6, outlet=3, 
        interface={65.0, 10.0}, outerface={100.0, 20.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=9, outlet=3, 
        interface={20.0, 100.0}, outerface={100.0, 20.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).

divide_rectangle_7_5_test() ->
    TR = #topological_region{inlet=7, outlet=5,square_flag=false,
        interface={65.0, 10.0}, outerface={120.0, 65.0},
        region=#region{left=10.0,top=100.0, right=120.0, bottom=20.0}},
    {Left,Right} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=6, outlet=3, 
        interface={65.0, 10.0}, outerface={100.0, 20.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=9, outlet=6, 
        interface={20.0, 100.0}, outerface={120.0, 65.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).

divide_rectangle_5_7_test() ->
    TR = #topological_region{inlet=5, outlet=7,square_flag=false,
        interface={120.0, 65.0}, outerface={65.0, 10.0},
        region=#region{left=10.0,top=100.0, right=120.0, bottom=20.0}},
    {Right,Left} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=3, outlet=6, 
        interface={100.0, 20.0}, outerface={65.0, 10.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=6, outlet=9, 
        interface={120.0, 65.0}, outerface={20.0, 100.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).

divide_rectangle_5_11_test() ->
    TR = #topological_region{inlet=5, outlet=11,square_flag=false,
        interface={120.0, 65.0}, outerface={10.0, 65.0},
        region=#region{left=10.0,top=100.0, right=120.0, bottom=20.0}},
    {Right,Left} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=3, outlet=0, 
        interface={100.0, 20.0}, outerface={10.0, 65.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=6, outlet=9, 
        interface={120.0, 65.0}, outerface={20.0, 100.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% (1, 2) -> [3,4,5,6,7,8,9,10,11] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
divide_square_1_3_test() ->
    TR = #topological_region{inlet=1, outlet=3,
        interface={65.0, 120.0}, outerface={100.0, 20.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Top,Bottom} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=1, outlet=7, square_flag=false,
        interface={65.0, 120.0}, outerface={65.0, 10.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=60.0}},
    ExpectBottom = #topological_region{inlet=11,outlet=3, square_flag=false,
        interface={10.0, 65.0}, outerface={60.0, 20.0},
        region=#region{left=10.0,top=60.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).

divide_square_2_3_test() ->
    TR = #topological_region{inlet=2, outlet=3,
        interface={100.0, 60.0}, outerface={60.0, 20.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Top,Bottom} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=3, outlet=7, square_flag=false,
        interface={100.0, 60.0}, outerface={65.0, 10.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=60.0}},
    ExpectBottom = #topological_region{inlet=11,outlet=3, square_flag=false,
        interface={10.0, 65.0}, outerface={60.0, 20.0},
        region=#region{left=10.0,top=60.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).

divide_square_1_4_test() ->
    TR = #topological_region{inlet=1, outlet=4,
        interface={65.0, 120.0}, outerface={60.0, 20.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Top,Bottom} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=1,outlet=7,square_flag=false,
        interface={65.0, 120.0}, outerface={65.0, 10.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=60.0}},
    ExpectBottom = #topological_region{inlet=11, outlet=3,square_flag=false,
        interface={10.0, 65.0}, outerface={60.0, 20.0},
        region=#region{left=10.0,top=60.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).    

divide_square_1_5_test() ->
    TR = #topological_region{inlet=1, outlet=5,
        interface={65.0, 120.0}, outerface={120.0, 65.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Top,Bottom} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=1,outlet=7,square_flag=false,
        interface={65.0, 120.0}, outerface={65.0, 10.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=60.0}},
    ExpectBottom = #topological_region{inlet=11, outlet=5,square_flag=false,
        interface={10.0, 65.0}, outerface={120.0, 65.0},
        region=#region{left=10.0,top=60.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).    

divide_square_2_5_test() ->
    TR = #topological_region{inlet=2, outlet=5,
        interface={100.0, 60.0}, outerface={120.0, 65.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Top,Bottom} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=3,outlet=7,square_flag=false,
        interface={100.0, 60.0}, outerface={65.0, 10.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=60.0}},
    ExpectBottom = #topological_region{inlet=11, outlet=5,square_flag=false,
        interface={10.0, 65.0}, outerface={120.0, 65.0},
        region=#region{left=10.0,top=60.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).    

divide_square_1_6_test() ->
    TR = #topological_region{inlet=1, outlet=6,
        interface={65.0, 120.0}, outerface={120.0, 10.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Top,Bottom} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=1,outlet=7,square_flag=false,
        interface={65.0, 120.0}, outerface={65.0, 10.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=60.0}},
    ExpectBottom = #topological_region{inlet=11, outlet=5,square_flag=false,
        interface={10.0, 65.0}, outerface={120.0, 65.0},
        region=#region{left=10.0,top=60.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).    

divide_square_2_6_test() ->
    TR = #topological_region{inlet=2, outlet=6,
        interface={100.0, 60.0}, outerface={120.0, 10.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Top,Bottom} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=3,outlet=7,square_flag=false,
        interface={100.0, 60.0}, outerface={65.0, 10.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=60.0}},
    ExpectBottom = #topological_region{inlet=11, outlet=5,square_flag=false,
        interface={10.0, 65.0}, outerface={120.0, 65.0},
        region=#region{left=10.0,top=60.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).    

divide_square_1_9_test() ->
    TR = #topological_region{inlet=1, outlet=9,
        interface={65.0, 120.0}, outerface={20.0, 100.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Right, Left} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=4,outlet=10,square_flag=false,
        interface={60.0, 20.0}, outerface={60.0, 100.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=0, outlet=8,square_flag=false,
        interface={65.0, 120.0}, outerface={20.0, 60.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).    

divide_square_2_9_test() ->
    TR = #topological_region{inlet=2, outlet=9,
        interface={100.0, 60.0}, outerface={20.0, 100.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Right, Left} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=4,outlet=10,square_flag=false,
        interface={60.0, 20.0}, outerface={60.0, 100.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=2, outlet=8,square_flag=false,
        interface={100.0, 60.0}, outerface={20.0, 60.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).    

divide_square_1_10_test() ->
    TR = #topological_region{inlet=1, outlet=10,
        interface={65.0, 120.0}, outerface={60.0, 100.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Right, Left} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=4,outlet=10,square_flag=false,
        interface={60.0, 20.0}, outerface={60.0, 100.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=0, outlet=8,square_flag=false,
        interface={65.0, 120.0}, outerface={20.0, 60.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).    

divide_square_2_10_test() ->
    TR = #topological_region{inlet=2, outlet=10,
        interface={100.0, 60.0}, outerface={60.0, 100.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Right, Left} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=4,outlet=10,square_flag=false,
        interface={60.0, 20.0}, outerface={60.0, 100.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=2, outlet=8,square_flag=false,
        interface={100.0, 60.0}, outerface={20.0, 60.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).    

divide_square_2_11_test() ->
    TR = #topological_region{inlet=2, outlet=11,
        interface={100.0, 60.0}, outerface={10.0, 65.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Right, Left} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=4,outlet=0,square_flag=false,
        interface={60.0, 20.0}, outerface={10.0, 65.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=2, outlet=8,square_flag=false,
        interface={100.0, 60.0}, outerface={20.0, 60.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).    

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
divide_square_4_0_test() ->
    TR = #topological_region{inlet=4, outlet=0,
        interface={60.0, 20.0}, outerface={10.0, 120.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Bottom, Top} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=7, outlet=1, square_flag=false,
        interface={65.0, 10.0}, outerface={65.0, 120.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=60.0}},
    ExpectBottom = #topological_region{inlet=3,outlet=11, square_flag=false,
        interface={60.0, 20.0}, outerface={10.0, 65.0},
        region=#region{left=10.0,top=60.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).

divide_square_8_10_test() ->
    TR = #topological_region{inlet=8, outlet=10,
        interface={20.0, 60.0}, outerface={60.0, 100.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Bottom,Top} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=5,outlet=9,square_flag=false,
        interface={120.0, 65.0}, outerface={60.0, 100.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=60.0}},
    ExpectBottom = #topological_region{inlet=9, outlet=1,square_flag=false,
        interface={20.0, 60.0}, outerface={65.0, 120.0},
        region=#region{left=10.0,top=60.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).    

divide_square_11_2_test() ->
    TR = #topological_region{inlet=11, outlet=2,
        interface={10.0, 65.0}, outerface={100.0, 60.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Left,Right} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=0, outlet=4,square_flag=false,
        interface={10.0, 65.0}, outerface={60.0, 20.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=8, outlet=2,square_flag=false,
        interface={20.0, 60.0}, outerface={100.0, 60.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).

%%%%%%%%%%%%%%%% 0 -> [1,2,3,4,5,6,7,8,9,10,11]
divide_square_0_1_test() ->
    TR = #topological_region{inlet=0, outlet=1,
        interface={10.0, 120.0}, outerface={65.0, 120.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Left,Right} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=0, outlet=4,square_flag=false,
        interface={10.0, 65.0}, outerface={60.0, 20.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=8, outlet=0,square_flag=false,
        interface={20.0, 60.0}, outerface={65.0, 120.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).
    
divide_square_0_2_test() ->
    TR = #topological_region{inlet=0, outlet=2,
        interface={10.0, 120.0}, outerface={100.0, 60.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Left,Right} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=0, outlet=4,square_flag=false,
        interface={10.0, 65.0}, outerface={60.0, 20.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=8, outlet=2,square_flag=false,
        interface={20.0, 60.0}, outerface={100.0, 60.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).

divide_square_0_3_test() ->
    TR = #topological_region{inlet=0, outlet=3,
        interface={10.0, 120.0}, outerface={100.0, 20.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Left,Right} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=0, outlet=4,square_flag=false,
        interface={10.0, 65.0}, outerface={60.0, 20.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=8, outlet=2,square_flag=false,
        interface={20.0, 60.0}, outerface={100.0, 60.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).

divide_square_0_4_test() ->
    TR = #topological_region{inlet=0, outlet=4,
        interface={10.0, 120.0}, outerface={60.0, 20.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Top,Bottom} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=1,outlet=7,square_flag=false,
        interface={65.0, 120.0}, outerface={65.0, 10.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=60.0}},
    ExpectBottom = #topological_region{inlet=11, outlet=3,square_flag=false,
        interface={10.0, 65.0}, outerface={60.0, 20.0},
        region=#region{left=10.0,top=60.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).

divide_square_0_5_test() ->
    TR = #topological_region{inlet=0, outlet=5,
        interface={10.0, 120.0}, outerface={120.0, 65.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Top,Bottom} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=1,outlet=7,square_flag=false,
        interface={65.0, 120.0}, outerface={65.0, 10.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=60.0}},
    ExpectBottom = #topological_region{inlet=11, outlet=5,square_flag=false,
        interface={10.0, 65.0}, outerface={120.0, 65.0},
        region=#region{left=10.0,top=60.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).

divide_square_0_7_test() ->
    TR = #topological_region{inlet=0, outlet=7,
        interface={10.0, 120.0}, outerface={65.0, 10.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Top,Bottom} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=11,outlet=5,square_flag=false,
        interface={10.0, 65.0}, outerface={120.0, 65.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=60.0}},
    ExpectBottom = #topological_region{inlet=1, outlet=7,square_flag=false,
        interface={65.0, 120.0}, outerface={65.0, 10.0},
        region=#region{left=10.0,top=60.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).

divide_square_0_8_test() ->
    TR = #topological_region{inlet=0, outlet=8,
        interface={10.0, 120.0}, outerface={20.0, 60.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Top,Bottom} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=11,outlet=5,square_flag=false,
        interface={10.0, 65.0}, outerface={120.0, 65.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=60.0}},
    ExpectBottom = #topological_region{inlet=1, outlet=9,square_flag=false,
        interface={65.0, 120.0}, outerface={20.0, 60.0},
        region=#region{left=10.0,top=60.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).

divide_square_0_10_test() ->
    TR = #topological_region{inlet=0, outlet=10,
        interface={10.0, 120.0}, outerface={60.0, 100.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Right, Left} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=4, outlet=10,square_flag=false,
        interface={60.0, 20.0}, outerface={60.0, 100.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=0, outlet=8,square_flag=false,
        interface={65.0, 120.0}, outerface={20.0, 60.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).

%%%%%%%%%%%%%%%% [3,6,9] -> 
%% 6
divide_square_3_7_test() ->
    TR = #topological_region{inlet=3, outlet=7,
        interface={100.0, 20.0}, outerface={65.0, 10.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Right,Left} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=2, outlet=6,square_flag=false,
        interface={100.0, 60.0}, outerface={65.0, 10.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=4, outlet=10,square_flag=false,
        interface={60.0, 20.0}, outerface={60.0, 100.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).

divide_square_3_5_test() ->
    TR = #topological_region{inlet=3, outlet=5,
        interface={100.0, 20.0}, outerface={92.5, 65.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Top,Bottom} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=3, outlet=7,square_flag=false,
        interface={100.0, 60.0}, outerface={65.0, 10.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=60.0}},
    ExpectBottom = #topological_region{inlet=11, outlet=5,square_flag=false,
        interface={10.0, 65.0}, outerface={92.5, 65.0},
        region=#region{left=10.0,top=60.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).

divide_square_3_8_test() ->
    TR = #topological_region{inlet=3, outlet=8,
        interface={100.0, 20.0}, outerface={20.0, 60.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Right,Left} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=2, outlet=8,square_flag=false,
        interface={100.0, 60.0}, outerface={20.0, 60.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=4, outlet=10,square_flag=false,
        interface={60.0, 20.0}, outerface={60.0, 100.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).

divide_square_3_11_test() ->
    TR = #topological_region{inlet=3, outlet=11,
        interface={100.0, 20.0}, outerface={10.0, 65.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Right,Left} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=4, outlet=0,square_flag=false,
        interface={60.0, 20.0}, outerface={10.0, 65.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=2, outlet=8,square_flag=false,
        interface={100.0, 60.0}, outerface={20.0, 60.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).

%% 6
divide_square_6_7_test() ->
    TR = #topological_region{inlet=5, outlet=7,
        interface={120.0, 65.0}, outerface={65.0, 10.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Right,Left} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=2, outlet=6,square_flag=false,
        interface={100.0, 60.0}, outerface={65.0, 10.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=6, outlet=10,square_flag=false,
        interface={120.0, 65.0}, outerface={60.0, 100.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).

divide_square_58_test() ->
    TR = #topological_region{inlet=5, outlet=8,
        interface={120.0, 92.5}, outerface={20.0, 60.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Right,Left} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=2, outlet=8,square_flag=false,
        interface={100.0, 60.0}, outerface={20.0, 60.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=6, outlet=10,square_flag=false,
        interface={120.0, 92.5}, outerface={60.0, 100.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).

divide_square_6_8_test() ->
    TR = #topological_region{inlet=6, outlet=8,
        interface={120.0, 10.0}, outerface={20.0, 60.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Right,Left} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=2, outlet=8,square_flag=false,
        interface={100.0, 60.0}, outerface={20.0, 60.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=6, outlet=10,square_flag=false,
        interface={120.0, 65.0}, outerface={60.0, 100.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).

divide_square_6_11_test() ->
    TR = #topological_region{inlet=6, outlet=11,
        interface={120.0, 10.0}, outerface={10.0, 65.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Bottom,Top} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=5, outlet=11,square_flag=false,
        interface={120.0, 65.0}, outerface={10.0, 65.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=60.0}},
    ExpectBottom = #topological_region{inlet=7, outlet=1,square_flag=false,
        interface={65.0, 10.0}, outerface={65.0, 120.0},
        region=#region{left=10.0,top=60.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).

%% 9
divide_square_9_7_test() ->
    TR = #topological_region{inlet=9, outlet=7,
        interface={20.0, 100.0}, outerface={65.0, 10.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Top, Bottom} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=9, outlet=5, square_flag=false,
        interface={60.0, 100.0}, outerface={120.0, 65.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=60.0}},
    ExpectBottom = #topological_region{inlet=1, outlet=7,square_flag=false,
        interface={65.0, 120.0}, outerface={65.0, 10.0},
        region=#region{left=10.0,top=60.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).

divide_square_9_5_test() ->
    TR = #topological_region{inlet=9, outlet=5,
        interface={20.0, 100.0}, outerface={120.0, 65.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Left,Right} = ?MO:divide(TR),
    ExpectLeft = #topological_region{inlet=8, outlet=2,square_flag=false,
        interface={20.0, 60.0}, outerface={100.0,60.0},
        region=#region{left=10.0,top=100.0,right=65.0,bottom=20.0}},
    ExpectRight = #topological_region{inlet=10, outlet=6,square_flag=false,
        interface={60.0, 100.0}, outerface={120.0, 65.0},
        region=#region{left=65.0,top=100.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectLeft, Left),
    ?assertEqual(ExpectRight, Right).

divide_square_9_11_test() ->
    TR = #topological_region{inlet=9, outlet=11,
        interface={20.0, 100.0}, outerface={10.0, 65.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=20.0}},
    {Bottom, Top} = ?MO:divide(TR),
    ExpectTop = #topological_region{inlet=5, outlet=11,square_flag=false,
        interface={120.0,65.0}, outerface={10.0, 65.0},
        region=#region{left=10.0,top=100.0,right=120.0,bottom=60.0}},
    ExpectBottom = #topological_region{inlet=9, outlet=1,square_flag=false,
        interface={20.0,60.0}, outerface={65.0, 120.0},
        region=#region{left=10.0,top=60.0,right=120.0,bottom=20.0}},
    ?assertEqual(ExpectTop, Top),
    ?assertEqual(ExpectBottom, Bottom).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
rotate_test() ->
    Region = #region{left=10.0,top=100.0,right=120.0,bottom=20.0},
    
    ExpectRegion = #region{left=20.0,top=-10.0,right=100.0,bottom=-120.0},
    ?assertEqual(ExpectRegion, rotate_cw_quarter(Region)),
    
    ExpectRegion2 = #region{left=-100.0,top=120.0,right=-20.0,bottom=10.0},
    ?assertEqual(ExpectRegion2, rotate_ccw_quarter(Region)), 
    
    ?assert(Region == rotate_cw_quarter(rotate_ccw_quarter(Region))),
    ?assertEqual(Region, rotate_ccw_quarter(rotate_cw_quarter(Region))).

rotate_region_taest() ->
    TR = #topological_region{inlet=1, outlet=3,
                region=#region{left=200.0,top=50.0,right=250.0,bottom=10.0}
            },
    ExpectTR = #topological_region{inlet=4, outlet=6,
                region=#region{left=200.0,top=60.0,right=240.0,bottom=10.0}
            },
    ?assertEqual(TR, rotate_counterclockwise_quarter(rotate_clockwise_quarter(TR))),
    ?assert(TR == rotate_clockwise_quarter(rotate_counterclockwise_quarter(TR))).
